home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / nn.zip / SEQUENCE.C < prev    next >
C/C++ Source or Header  |  1989-12-31  |  10KB  |  504 lines

  1. /*
  2.  * read presentation sequence file
  3.  */
  4.  
  5. #include "config.h"
  6. #include "debug.h"
  7.  
  8. export group_header *group_sequence;
  9. export char *read_mail = NULL;
  10. export int also_unsub_groups = 0;
  11. export int also_subgroups = 1;
  12.  
  13. static int seq_break_enabled = 1;    /* !! enabled */
  14.  
  15. static group_header *tail_sequence = NULL;
  16. static group_header *final_sequence = NULL;
  17.  
  18. static int gs_more_groups;
  19.  
  20.  
  21. only_folder_args(args)
  22. char **args;
  23. {
  24.     register char *arg;
  25.  
  26.     while (arg = *args++) {
  27.     if (*arg == '+' || *arg == '~' || *arg == '/') continue;
  28.     if (file_exist(arg, "fr")) continue;
  29.     return 0;
  30.     }
  31.     return 1;
  32. }
  33.  
  34.  
  35. named_group_sequence(groups)
  36. char **groups;
  37. {
  38.     register group_header *gh;
  39.     group_header *get_group_search();
  40.     register char *group;
  41.     int found, any, errors;
  42.  
  43.     group_sequence = NULL;
  44.     also_subgroups = 0;
  45.     
  46.     any = errors = 0;
  47.     while (group = *groups++) {
  48.         
  49.     if (gh = lookup(group)) {
  50.         if (gh->group_flag & G_DONE) continue;
  51.         any++;
  52.         enter_normal(gh);
  53.         continue;
  54.     }
  55.  
  56.     if (file_exist(group, "fr")) {
  57.         faked_entry(group, G_FOLDER);
  58.         any++;
  59.         continue;
  60.     }
  61.  
  62.     if (*group == '+' || *group == '~') {
  63.         char exp_file[FILENAME];
  64.         group_header fake_group;
  65.         
  66.         current_group = &fake_group;
  67.         fake_group.group_name = group;
  68.         group_file_name = NULL;
  69.         if (expand_file_name(exp_file, group) && file_exist(exp_file, "fr")) {
  70.         faked_entry(copy_str(exp_file), G_FOLDER);
  71.         any++;
  72.         continue;
  73.         }
  74.  
  75.         printf("Folder %s not found\n", group); fl;
  76.         errors++;
  77.         continue;
  78.     }
  79.     
  80.     found = 0;
  81.     start_group_search(group);
  82.     while (gh = get_group_search()) {
  83.         gh->group_flag |= G_DONE;
  84.         if ((gh->group_flag & G_SUBSCRIPTION) == 0 && !also_unsub_groups)
  85.         continue;
  86.         found++;
  87.         enter_normal(gh);
  88.     }
  89.      
  90.     if (!found) {
  91.         printf("Group %s not found\n", group); fl;
  92.         errors++;
  93.     } else
  94.         any++;
  95.     }
  96.  
  97.     end_sequence();
  98.     
  99.     if (errors) user_delay(2);
  100.     
  101.     return any;
  102. }
  103.  
  104. FILE *loc_seq_hook = NULL;    /* sequence in local "init" file */
  105. FILE *glob_seq_hook = NULL;    /* sequence in global "init" file */
  106.  
  107. normal_group_sequence()
  108. {
  109.     register group_header *gh;
  110.  
  111.     group_sequence = NULL;
  112.     gs_more_groups = 1;
  113.     
  114.     /* visit_p_f returns non-zero if terminated by !! */
  115.  
  116.     if (visit_presentation_file(nn_directory, "seq", loc_seq_hook))
  117.     goto final;
  118.     
  119.     if (visit_presentation_file(lib_directory, "sequence", glob_seq_hook))
  120.     goto final;
  121.     
  122.     Loop_Groups_Sorted(gh) {
  123.     if (gh->group_flag & G_DONE) continue;
  124.     
  125.     if ((gh->group_flag & G_SUBSCRIPTION) == 0 && !also_unsub_groups)
  126.         continue;
  127.  
  128.     enter_normal(gh);
  129.     }
  130.  
  131.  final:
  132.     if (final_sequence) {
  133.     enter_normal(final_sequence);
  134.     tail_sequence = NULL;
  135.     }
  136.  
  137. #ifdef MAIL_READING
  138.     mail_check();
  139. #endif
  140.     
  141.     end_sequence();
  142. }
  143.  
  144. static end_sequence()
  145. {
  146.     register group_header *gh, *backp;
  147.     register int seq_ix;
  148.     
  149.     if (tail_sequence)
  150.     tail_sequence->next_group = NULL;
  151.     
  152.     /* set up backward pointers */
  153.  
  154.     backp = NULL;
  155.     gh = group_sequence; 
  156.     seq_ix = 0;
  157.     while (gh) {
  158.     gh->preseq_index = ++seq_ix;
  159.     gh->prev_group = backp;
  160.     backp = gh;
  161.     gh = gh->next_group;
  162.     }
  163.  
  164. #ifdef SEQ_DUMP
  165.     if (Debug & SEQ_DUMP) {
  166.     for (gh = group_sequence; gh; gh = gh->next_group)
  167.         printf("%s\t", gh->group_name);
  168.     putchar(NL);
  169.  
  170.     nn_exit(0);
  171.     }
  172. #endif
  173.     
  174. }
  175.  
  176. #ifdef MAIL_READING
  177. static mail_check()
  178. {
  179.     static group_header mail_group;
  180.     struct stat st;
  181.     
  182.     if (read_mail == NULL) return;
  183.     if (stat(read_mail, &st) < 0) return;
  184.     if (st.st_size == 0 || st.st_mtime < st.st_atime) return;
  185.     
  186.     mail_group.group_name = read_mail;
  187.     gh->group_flag = G_FOLDER | G_MAILBOX | G_READ;
  188.  
  189.     /* "invent" an unread article for read_news */
  190.     gh->last_article = 1;
  191.     gh->last_l_article = 2;
  192.     
  193.     
  194.     if (tail_sequence) {
  195.     mail_group.next_group = group_sequence;
  196.     group_sequence = mail_group;
  197.     } else
  198.     enter_normal(&mail_group);
  199. }
  200. #endif
  201.  
  202. static visit_presentation_file(directory, seqfile, hook)
  203. char *directory, *seqfile;
  204. FILE *hook;
  205. {
  206.     import int group_name_args;
  207.     
  208.     register FILE *sf;
  209.     register c;
  210.     register group_header *gh;
  211.     group_header *get_group_search();
  212.     char group[FILENAME];
  213.     char savefile[FILENAME], *dflt_save, *enter_macro;
  214.     extern char *parse_enter_macro();
  215.     register char *gp;
  216.     int mode;
  217.     
  218. #define    SHOW_NORMAL    0    /*   : put this in at current pos */
  219. #define    SHOW_NEVER    1    /* ! : ignore these groups */
  220. #define    SHOW_FIRST    2    /* < : show these groups first */
  221. #define    SHOW_LAST    3    /* > : show this as late as possible */
  222.  
  223. #define    SHOW_MODES    " !<>"
  224.  
  225.     if (gs_more_groups == 0) return 0;
  226.     
  227.     if (hook != NULL)
  228.     sf = hook;    /* hook to init file */
  229.     else
  230.     if ((sf = open_file(relative(directory, seqfile), OPEN_READ)) == NULL)
  231.         return 0;
  232.  
  233. #ifdef SEQ_TEST
  234.     if (Debug & SEQ_TEST)
  235.     printf("Sequence file %s/%s\n", directory, seqfile);
  236. #endif
  237.     
  238.     mode = SHOW_NORMAL;
  239.     savefile[0] = NUL;
  240.     
  241.     while (gs_more_groups) {
  242.     
  243.     if ((c = getc(sf)) == EOF) break;
  244.     if (!isascii(c) || isspace(c)) continue;
  245.  
  246.     switch (c) {
  247.      case '!':
  248.         if (mode == SHOW_NEVER && seq_break_enabled) {
  249.         fclose(sf);
  250.         return 1;
  251.         }
  252.         
  253.         mode = SHOW_NEVER;
  254.         continue;
  255.  
  256.      case '<':
  257.         mode = SHOW_FIRST;
  258.         continue;
  259.         
  260.      case '>':
  261.         mode = SHOW_LAST;
  262.         continue;
  263.  
  264.      case '@':
  265.         seq_break_enabled = 0;
  266.         mode = SHOW_NORMAL;
  267.         continue;
  268.         
  269.      case '#':
  270.         do c = getc(sf);
  271.         while (c != EOF && c != NL);
  272.         mode = SHOW_NORMAL;
  273.         continue;
  274.  
  275.     }
  276.     
  277.     gp = group; 
  278.     do {
  279.         *gp++ = c;
  280.         c = getc(sf);
  281.     } while (c != EOF && isascii(c) && !isspace(c));
  282.     
  283.     *gp = NUL;
  284.     
  285.     while (c != EOF && (!isascii(c) || isspace(c))) c = getc(sf);
  286.     if (c == '+' || c == '~' || c == '/') {
  287.         gp = savefile;
  288.         if (c == '+') {
  289.         c = getc(sf);
  290.         if (c == EOF || (isascii(c) && isspace(c)))
  291.             goto use_same_savefile;
  292.         *gp++ = '+';
  293.         }
  294.         do {
  295.         *gp++ = c;
  296.         c = getc(sf);
  297.         } while (c != EOF && isascii(c) && !isspace(c));
  298.         *gp = NUL;
  299.         dflt_save = savefile[0] ? copy_str(savefile) : NULL;
  300.     } else
  301.         dflt_save = NULL;
  302.  
  303.      use_same_savefile:    
  304.     while (c != EOF && (!isascii(c) || isspace(c))) c = getc(sf);
  305.     if (c == '(') {
  306.         enter_macro = parse_enter_macro(sf, getc(sf));
  307.     } else {
  308.         enter_macro = NULL;
  309.         if (c != EOF) ungetc(c, sf);
  310.     }
  311.     
  312.     start_group_search(group);
  313.     
  314.     while (gh = get_group_search()) {
  315.         gh->group_flag |= G_DONE;
  316.  
  317.         gh->save_file = dflt_save;
  318.         if (gh->enter_macro == NULL) /* not set by "on entry" */
  319.         gh->enter_macro = enter_macro;
  320.         
  321.         if (group_name_args == 0 &&
  322.         (gh->group_flag & G_SUBSCRIPTION) == 0 && !also_unsub_groups)
  323.         continue;
  324.  
  325. #ifdef SEQ_TEST
  326.         if (Debug & SEQ_TEST && mode != SHOW_NORMAL)
  327.         printf("SEQ(%c), %s\n", SHOW_MODES[mode], gh->group_name);
  328. #endif
  329.         
  330.         switch (mode) {
  331.          case SHOW_FIRST:
  332.         if (tail_sequence) {
  333.             gh->next_group = group_sequence;
  334.             group_sequence = gh;
  335.             break;
  336.         }
  337.         /* fall thru */
  338.  
  339.          case SHOW_NORMAL:
  340.         enter_normal(gh);
  341.         break;
  342.         
  343.          case SHOW_NEVER:
  344.         break;
  345.         
  346.          case SHOW_LAST:
  347.         gh->next_group = final_sequence;
  348.         final_sequence = gh;
  349.         break;
  350.         }
  351.     }
  352.     
  353.     mode = SHOW_NORMAL;
  354.     }        
  355.  
  356.     fclose(sf);
  357.     return 0;
  358. }
  359.  
  360.  
  361. static enter_normal(gh)
  362. group_header *gh;
  363. {
  364.     gh->group_flag |= G_DONE;
  365.     if (tail_sequence)
  366.     tail_sequence->next_group = gh;
  367.     else
  368.     group_sequence = gh;
  369.         
  370.     tail_sequence = gh;
  371.  
  372. #ifdef SEQ_TEST
  373.     if (Debug & SEQ_TEST)
  374.         printf("SEQ(NORMAL) %s\n", gh->group_name);
  375. #endif
  376. }
  377.  
  378.  
  379. static faked_entry(name, flag)
  380. char *name;
  381. int32 flag;
  382. {
  383.     group_header *gh;
  384.     
  385.     gh = (group_header *)calloc(1, sizeof(group_header));
  386.     mem_check((char *)gh, 1, "group header");
  387.     
  388.     gh->group_name = name;
  389.     gh->group_flag = flag | G_READ;
  390.  
  391.     /* "invent" an unread article for read_news */
  392.     gh->last_article = 1;
  393.     gh->last_l_article = 2;
  394.     
  395.     enter_normal(gh);
  396. }
  397.  
  398.  
  399. static char *gs_group;
  400. static int gs_length, gs_index, gs_mode;
  401. static group_header *gs_only_group = NULL;
  402.  
  403. #define GS_PREFIX0    0    /* group (or group*) */
  404. #define    GS_PREFIX    1    /* group. */
  405. #define    GS_SUFFIX    2    /* .group */
  406. #define GS_INFIX    3    /* .group. */
  407. #define GS_NEW_GROUP    4    /* new group */
  408. #define GS_ALL        5    /* all / . */
  409.  
  410. start_group_search(group)
  411. char *group;
  412. {
  413.     char *dot;
  414.     int last;
  415.     
  416.     gs_index = master.number_of_groups;
  417.     if ((last = strlen(group) - 1) < 0) return;
  418.     if (group[last] == '*')
  419.     group[last] = NUL;
  420.     else
  421.     if (!also_subgroups && (gs_only_group = lookup(group)) != NULL)
  422.         return;
  423.     
  424.     if (strcmp(group, "NEW") == 0) {
  425.     gs_mode = GS_NEW_GROUP;
  426.     gs_length = 0;
  427.     } else 
  428.     if (strcmp(group, "all") == 0 || strcmp(group, ".") == 0) {
  429.     gs_mode = GS_ALL;
  430.     gs_length = 0;
  431.     } else {
  432.     gs_mode = GS_PREFIX0;
  433.     
  434.     if (strncmp(group, "all.", 4) == 0) group += 3;
  435.     
  436.     if (*group == '.') gs_mode = GS_SUFFIX;
  437.     
  438.     if ((dot = strrchr(group, '.')) != NULL && dot != group) {
  439.         if (dot[1] == NUL || strcmp(dot+1, "all") == 0) {
  440.         dot[1] = NUL;
  441.         gs_mode = (gs_mode == GS_SUFFIX) ? GS_INFIX : GS_PREFIX;
  442.         }
  443.     }
  444.     
  445.     gs_length = strlen(group);
  446.     gs_group = group;
  447.     }    
  448.  
  449.     gs_index = 0;
  450.     gs_more_groups = 0;
  451. }
  452.  
  453.  
  454. group_header *get_group_search()
  455. {
  456.     register group_header *gh;
  457.     register int c, tail;
  458.     
  459.     if (gs_only_group != NULL) {
  460.     gh = gs_only_group;
  461.     gs_only_group = NULL;
  462.     if (gh->group_flag & (G_DONE | G_NO_DIRECTORY)) return NULL;
  463.     return gh;
  464.     }
  465.     
  466.     while (gs_index < master.number_of_groups) {
  467.     gh = sorted_groups[gs_index++];
  468.     if (gh->group_flag & (G_DONE | G_NO_DIRECTORY)) continue;
  469.  
  470.     gs_more_groups++;
  471.  
  472.     if ((tail = gh->group_name_length - gs_length) < 0) continue;
  473.     
  474.     switch (gs_mode) {
  475.         
  476.      case GS_NEW_GROUP:
  477.         if ((gh->group_flag & G_NEW) == 0) continue;
  478.         break;
  479.         
  480.      case GS_PREFIX0:
  481.         if ((c = (gh->group_name)[gs_length]) != NUL && c != '.') continue;
  482.      case GS_PREFIX:
  483.         if (strncmp(gh->group_name, gs_group, gs_length)) continue;
  484.         break;
  485.         
  486.      case GS_SUFFIX:
  487.         if (strcmp(gh->group_name + tail, gs_group)) continue;
  488.         break;
  489.         
  490.      case GS_INFIX:
  491.         user_error(".name. notation not supported (yet)");
  492.         break;
  493.  
  494.      case GS_ALL:
  495.         break;
  496.     }
  497.  
  498.     gs_more_groups--;
  499.     return gh;
  500.     }
  501.     
  502.     return NULL;
  503. }
  504.